//
//  TLVideoPlayer.m
//  FunnyVideo
//
//  Created by 李鑫 on 15/8/18.
//  Copyright © 2015年 NewEggTech. All rights reserved.
//

#import "TLVideoPlayer.h"
#import "VideoLoadHUD.h"

//#import ""

@interface TLVideoPlayer ()

@property (nonatomic,strong) VideoPlayerCallback callBack;

@property (nonatomic,strong) AVPlayerLayer *v_layer;

@property (nonatomic,strong) CALayer *o_layer;

@property (nonatomic,strong) AVPlayerItem       *videoItem;

@property (nonatomic,strong) UIButton      *playButton;

@property (nonatomic,strong) UIActivityIndicatorView *indicatorView;


//Add gesture
//@property (nonatomic,strong) UITapGestureRecognizer *tapGesture;
@end
@implementation TLVideoPlayer

@synthesize videoPlayer,videoItem;

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

#pragma mark -- Life Cycle
- (id)initWithCoder:(nonnull NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if(self)
    {
        self.playerStatus = TLPlayerStatusUnLoaded;
        
        //Play Button
        self.playButton = (UIButton *)[self viewWithTag:19];
        
        self.playButton.center = self.center;
        
        [self.playButton addTarget:self action:@selector(playButtonDidClick:) forControlEvents:UIControlEventTouchUpInside];
        
        //self.o_layer = [self.playButton.layer superlayer];
        
        //Add gesture
     //   self.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(playerDidClick:)];
        self.layer.cornerRadius = 4.f;
        self.layer.masksToBounds = YES;
        
        [self addIndicator];
        
        
    }
    
    return self;
}

#pragma mark -- Add Indicator
- (void)addIndicator{
    //Install ActivityIndicator
    self.indicatorView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
    [self.indicatorView setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
    [self.indicatorView setColor:TintColor];
    self.indicatorView.translatesAutoresizingMaskIntoConstraints = NO;
    [self addSubview:self.indicatorView];
    
    [self.indicatorView setHidesWhenStopped:YES];
    
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.indicatorView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
    
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.indicatorView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
}


#pragma mark -- Video Layer
+ (Class)videoLayer{
    return [AVPlayerLayer class];
}

#pragma mark -- Player Action
- (void)play{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.playButton setHidden:YES];
        
        if(self.playerStatus == TLPlayerStatusPaused)
        {
            [self.layer addSublayer:self.v_layer];
            [self.videoPlayer play];
            self.playerStatus= TLPlayerStatusPlaying;
            return ;
        }
        else
        {
        //显示加载进度条
        [self showLoadingHUD];
        AVAsset *asset = [AVURLAsset URLAssetWithURL:self.url options:nil];
        AVPlayerItem *anItem = [AVPlayerItem playerItemWithAsset:asset];
        
        videoPlayer = [AVPlayer playerWithPlayerItem:anItem];
        
        [videoPlayer.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
        
        [videoPlayer.currentItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(avItemStatusDidChanged:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
        
        [self setVideoLayer:[AVPlayerLayer playerLayerWithPlayer:videoPlayer]];
        }
    });
}

- (void)videoDidPlay{
    [self reset];
}

- (void)pause{
    [[self player] pause];
    [self.v_layer removeFromSuperlayer];
    [self.playButton setHidden:NO];
    self.playerStatus = TLPlayerStatusPaused;
    
}

- (void)stop{
    [self removeObserverAndNotificationCenter];
    [[self player] replaceCurrentItemWithPlayerItem:nil];
    [self.v_layer removeFromSuperlayer];
    [self.playButton setHidden:NO];
    self.playerStatus = TLPlayerStatusUnLoaded;
}

- (void)reset{
    //UI Update
    [self.playButton setHidden:NO];
    
    [self dismissLoadingHUD];
    
    self.callBack(TLVideoPlayerEventTypeValueChanged,0);
    //KVO remove
        [self removeObserverAndNotificationCenter];
    
    //Video Layer Update and Stop Load Video
    [self.v_layer removeFromSuperlayer];
    [self.videoPlayer replaceCurrentItemWithPlayerItem:nil];
    self.videoPlayer = nil;
   
    //state
    self.playerStatus = TLPlayerStatusUnLoaded;
}

#pragma mark -- AVPlayer Relation
-(AVPlayer*)player{
    return videoPlayer;
}

- (void)setVideoLayer:(AVPlayerLayer *)layer{
    
    self.o_layer = [[self.layer sublayers] lastObject];
    
    self.v_layer = layer;
    
    layer.frame = CGRectMake(0, 0, self.layer.frame.size.width, self.layer.frame.size.height);
    layer.videoGravity = AVLayerVideoGravityResizeAspectFill;

    
    [self.layer addSublayer:layer];
}

- (void)setPlayerDisplayMode:(TLPlayerDisplayMode)displayMode{
    switch (displayMode) {
        case TLPlayerDisplayModeCenter:
        {}
            break;
        case TLPlayerDisplayModeFull:
        {}
            break;
            default:
        {}
            break;
    }
}

- (void)avItemStatusDidChanged:(NSNotification*)notification{
    NSLog(@"%@",notification);
    //AVPlayerItem *playItem = [notification object];
    if([[notification name] isEqualToString:@"AVPlayerItemDidPlayToEndTimeNotification"])
    {
        [self reset];
    }
}

#pragma mark -- Add Block
- (void)addPlayerEventCallBack:(VideoPlayerCallback)block{
    self.callBack = block;
}

- (void)playButtonDidClick:(UIButton *)btn{
    if(!self.callBack)
        return;
    if(self.playerStatus == TLPlayerStatusUnLoaded || TLPlayerStatusPaused)
    {
        self.callBack(TLVideoPlayerEventPlay,1);
    }
    
    if(self.playerStatus == TLPlayerStatusPlaying)
    {
        self.callBack(TLVideoPlayerEventPause,1);
    }
}

#pragma mark -- Play
- (void)touchesEnded:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
    NSLog(@"%ld",(long)[[[touches allObjects] lastObject] phase]);
    NSLog(@"%d",self.playButton.hidden);
    if([(UITouch*)[[touches allObjects] lastObject] tapCount] == 1 && [(UITouch*)[[touches allObjects] lastObject] phase] == UITouchPhaseEnded)
    {
    if((self.playerStatus == TLPlayerStatusPaused) || (self.playerStatus == TLPlayerStatusUnLoaded))
        self.callBack(TLVideoPlayerEventPlay,1);
    
    if(self.playerStatus == TLPlayerStatusPlaying)
        self.callBack(TLVideoPlayerEventPause,1);
    }
}

#pragma mark -- Show Time Progress
- (void)showTimeProgressWithSecond:(NSUInteger)sec{
    dispatch_async(dispatch_get_main_queue(), ^{
       //show time view
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(sec * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            //dismiss time view
            
        });
    });
}

- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary *)change context:(nullable void *)context{
    //开始播放
    if([keyPath isEqualToString:@"status"] && [change[@"kind"] integerValue] == AVPlayerStatusReadyToPlay)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self dismissLoadingHUD];
            
            self.playerStatus= TLPlayerStatusPlaying;
            
            [videoPlayer play];
        });
    }
    else if ([keyPath isEqualToString:@"loadedTimeRanges"])
    {
        //Update Progress
        AVPlayerItem *obj = (AVPlayerItem *)object;
       float value = [obj duration].value/[obj duration].timescale;
        float curTime = ([obj currentTime].value/[obj currentTime].timescale)/value;
        if(self.callBack)
        self.callBack(TLVideoPlayerEventTypeValueChanged,curTime);
        
        NSLog(@"当前播放时间 : %f",curTime);
    }
}

- (NSTimeInterval)availableDuration {
    NSArray *loadedTimeRanges = [[self.videoPlayer currentItem] loadedTimeRanges];
    CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域
    float startSeconds = CMTimeGetSeconds(timeRange.start);
    float durationSeconds = CMTimeGetSeconds(timeRange.duration);
    NSTimeInterval result = startSeconds + durationSeconds;// 计算缓冲总进度
    
    return result;
}

#pragma mark -- HUD
- (void)showLoadingHUD{
    [self.indicatorView startAnimating];
}

- (void)dismissLoadingHUD{
        [self.indicatorView stopAnimating];
}


- (void)dealloc{
    [self removeObserverAndNotificationCenter];
}

- (void)removeObserverAndNotificationCenter{
    [videoPlayer.currentItem removeObserver:self forKeyPath:@"status"];
    [videoPlayer.currentItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
    [[NSNotificationCenter defaultCenter]  removeObserver:self];
        
}

@end
